package com.elitel.frame.base.service.impl;

import com.elitel.common.utils.UUIDUtil;
import com.elitel.frame.base.service.AcAppCatalogService;
import com.elitel.frame.base.service.AcAppStationService;
import com.elitel.frame.base.service.AcStationPushRecordService;
import com.elitel.frame.main.dao.AcAppCatalogMapper;
import com.elitel.frame.main.dao.AcAppServiceMapper;
import com.elitel.frame.main.dao.AcAppStationMapper;
import com.elitel.frame.main.dao.ext.ExtAcAppCatalogMapper;
import com.elitel.frame.main.dao.ext.ExtSysPrjserviceMapper;
import com.elitel.frame.main.entity.AcAppService;
import com.elitel.frame.main.entity.SysPrjservice;
import com.elitel.frame.main.entity.acappcatalog.AcAppCatalog;
import com.elitel.frame.main.entity.acappcatalog.AcAppCatalogDTO;
import com.elitel.frame.main.entity.acappcatalog.AcAppCatalogExample;
import com.elitel.frame.main.entity.acappstation.AcAppStation;
import com.elitel.frame.main.entity.acappstation.AcAppStationExample;
import com.elitel.frame.main.entity.acstationinfo.AcStationInfo;
import com.elitel.frame.main.entity.constant.TmpUser;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 访问控制-应用和测站分类(AcAppCatalog)表服务实现类
 *
 * @author makejava
 * @since 2023-11-11 15:15:43
 */
@Service("acAppCatalogService")
public class AcAppCatalogServiceImpl implements AcAppCatalogService {
    @Resource
    private ExtAcAppCatalogMapper extAcAppCatalogMapper;
    @Resource
    private AcAppCatalogMapper acAppCatalogMapper;
    @Resource
    private AcAppStationService acAppStationService;
    @Resource
    private AcAppStationMapper acAppStationMapper;
    @Resource
    private AcStationPushRecordService acStationPushRecordService;
    @Resource
    private AcAppServiceMapper acAppServiceMapper;
    @Resource
    private ExtSysPrjserviceMapper extSysPrjserviceMapper;
    

    /**
     * 通过ID查询单条数据
     *
     * @param catalogId 主键
     * @return 实例对象
     */
    @Override
    public AcAppCatalog queryById(String catalogId) {
        return this.acAppCatalogMapper.selectByPrimaryKey(catalogId);
    }


    /**
     * 新增数据
     *
     * @param acAppCatalog 实例对象
     * @return 实例对象
     */
    @Override
    public AcAppCatalog insert(AcAppCatalog acAppCatalog) {
        this.acAppCatalogMapper.insert(acAppCatalog);
        return acAppCatalog;
    }

    /**
     * 修改数据
     *
     * @param acAppCatalog 实例对象
     * @return 实例对象
     */
    @Override
    public AcAppCatalog update(AcAppCatalog acAppCatalog) {
        this.acAppCatalogMapper.updateByPrimaryKeySelective(acAppCatalog);
        return this.queryById(acAppCatalog.getCatalogId());
    }

    /**
     * 通过主键删除数据
     *
     * @param catalogId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(String catalogId) {
        return this.acAppCatalogMapper.deleteByPrimaryKey(catalogId) > 0;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(AcAppCatalogDTO dto) {
        String catalogId = dto.getCatalogId();
        dto.setCatalogId(StringUtils.isEmpty(catalogId) ? UUIDUtil.randomUUID() : catalogId);
        // 分组关联的站点数量
        int stationSaveNum = acAppStationService.save(dto);
        dto.setStationNum(stationSaveNum);
        AcAppCatalog acAppCatalog = acAppCatalogMapper.selectByPrimaryKey(catalogId);
        if (acAppCatalog == null) {
            // 新增
            dto.setCreatedUser(TmpUser.ADMIN);
            dto.setCreatedTime(new Date());
            acAppCatalogMapper.insertSelective(dto);
        } else {
            // 编辑
            dto.setUpdatedTime(new Date());
            dto.setUpdatedUser(TmpUser.ADMIN);
            acAppCatalogMapper.updateByPrimaryKeySelective(dto);
        }
        acStationPushRecordService.save(Collections.singletonList(dto));
    }

    @Override
    public List<AcStationInfo> selectStations(AcAppCatalogDTO dto) {
        return null;
    }

    @Override
    public List<AcAppCatalogDTO> selectList(AcAppCatalogDTO dto) {
        List<AcAppCatalogDTO> resList = new ArrayList<>();
        List<AcAppCatalog> acAppCatalogs;
        if (CollectionUtils.isEmpty(dto.getAppIdList())) {
            acAppCatalogs = this.extAcAppCatalogMapper.queryList(dto);
        } else {
            AcAppCatalogExample acAppCatalogExample = new AcAppCatalogExample();
            acAppCatalogExample.createCriteria().andAppIdIn(dto.getAppIdList());
            acAppCatalogs = this.acAppCatalogMapper.selectByExample(acAppCatalogExample);
        }
        // 查询到分组信息
        if (CollectionUtils.isEmpty(acAppCatalogs)) {
            return resList;
        }

        // 根据分组id查询数据
        List<String> catalogIdList = acAppCatalogs.stream().map(AcAppCatalog::getCatalogId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        AcAppStationExample stationExample = new AcAppStationExample();
        stationExample.createCriteria().andCatalogIdIn(catalogIdList);
        List<AcAppStation> acAppStations = acAppStationMapper.selectByExample(stationExample);
        Map<String, List<AcAppStation>> idListMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(acAppStations)) {
            idListMap = acAppStations.stream().collect(Collectors.groupingBy(AcAppStation::getCatalogId));
        }
        // 封装结果集
        for (AcAppCatalog acAppCatalog : acAppCatalogs) {
            AcAppCatalogDTO res = new AcAppCatalogDTO();
            BeanUtils.copyProperties(acAppCatalog, res);
            res.setAppStationList(idListMap.get(acAppCatalog.getCatalogId()));
            resList.add(res);
        }
        return resList;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteByIds(String catalogIds) {
        // 删除之前先校验
        this.beforeDel(catalogIds);
        // 删除分组关联的分组信息
        List<String> catalogIdList = Arrays.asList(catalogIds.split(","));
        AcAppStationExample stationExample = new AcAppStationExample();
        stationExample.createCriteria().andCatalogIdIn(catalogIdList);
        acAppStationMapper.deleteByExample(stationExample);

        // 删除分组信息
        AcAppCatalogExample example = new AcAppCatalogExample();
        example.createCriteria().andCatalogIdIn(catalogIdList);
        return this.acAppCatalogMapper.deleteByExample(example);
    }

    private void beforeDel(String catalogIds) {
        if (StringUtils.isEmpty(catalogIds)) {
            throw new RuntimeException("分组id不能为空");
        }
        List<AcAppService> acAppServices = acAppServiceMapper.selectByCatalogIds(Arrays.asList(catalogIds.split(",")));
        if (CollectionUtils.isEmpty(acAppServices)) {
            return;
        }
        
        
        List<String> guids = acAppServices.stream().map(AcAppService::getServiceId).collect(Collectors.toList());
        List<SysPrjservice> sysPrjservices = extSysPrjserviceMapper.geServiceList(null, guids);
        String serviceNames = sysPrjservices.stream().map(SysPrjservice::getServicename).distinct().collect(Collectors.joining(","));
        if (serviceNames.isEmpty()) return;
        throw new RuntimeException("当前分组已经被服务【" + serviceNames + "】绑定, 请解除绑定后再删除");
    }

    @Override
    public Map<String, List<AcAppCatalogDTO>> selectListByAppIds(AcAppCatalogDTO dto) {
        List<AcAppCatalogDTO> acAppCatalogDTOS = this.selectList(dto);
        return acAppCatalogDTOS.stream().collect(Collectors.groupingBy(AcAppCatalog::getAppId));
    }
}
